package com.example.androidproject.online.activity;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.OpenableColumns;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.example.androidproject.databinding.FragmentChat2Binding;
import com.example.androidproject.online.Client;
import com.example.androidproject.online.Server;
import com.example.androidproject.online.adapter.OnlineChatAdapter;
import com.example.androidproject.online.pojo.ChatInfo;
import com.example.androidproject.sqlite.FileRepository;
import com.example.androidproject.sqlite.MessageRepository;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class OnlineChatActivity extends AppCompatActivity {
    private static final int PORT = 1122;
    private static final int REQUEST_CODE_PICK_FILE = 1;
    private FragmentChat2Binding binding;
    private String identity;
    //不单是服务器，准确说是对方
    private String serverAddress;
    private Client client;
    private Server server;
    private ArrayList<ChatInfo> list = new ArrayList<>();
    private OnlineChatAdapter adapter;
    private MessageRepository messageRepository;
    private FileRepository fileRepository;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = FragmentChat2Binding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.progressBar.setVisibility(View.GONE);

        Intent intent = getIntent();
        identity = intent.getStringExtra("identity");
        serverAddress = intent.getStringExtra("serverAddress");
        //serverAddress作为表名部分
        String tableName = "t" + serverAddress.replace(".", "");
        Log.e("???", "onCreate:" + tableName);
        messageRepository = new MessageRepository(binding.getRoot().getContext(), tableName);
        fileRepository = new FileRepository(this);

        adapter = new OnlineChatAdapter(list);
        binding.chatRecylerView.setAdapter(adapter);
        binding.chatRecylerView.setLayoutManager(new LinearLayoutManager(this));

        handleByIdentity();

        binding.imageBack.setOnClickListener(v -> {
            close();
            finish();
        });

        binding.layoutSend.setOnClickListener(v -> {
            String message = binding.inputMessage.getText().toString();
            //0,自己；1,对方
            messageRepository.insertMessage(message, 0);

            if (!message.trim().isEmpty()) {
                if ("client".equals(identity) && client != null) {
                    sendClientMessage(message);
                } else if ("service".equals(identity) && server != null) {
                    sendServerMessage(message);
                }
            }
            binding.inputMessage.setText("");
        });

        binding.buttonSendFile.setOnClickListener(v -> {
            Intent filePickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
            filePickerIntent.setType("*/*");
            startActivityForResult(filePickerIntent, REQUEST_CODE_PICK_FILE);
        });

        binding.chatRecylerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                // 在布局完成后滚动到底部
                binding.chatRecylerView.scrollToPosition(binding.chatRecylerView.getAdapter().getItemCount() - 1);
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_PICK_FILE && resultCode == RESULT_OK) {
            Uri fileUri = data.getData();
            if (fileUri != null) {
                String fileName = getFileName(fileUri);
                File file = new File(getCacheDir(), fileName);
                new Thread(() -> handleFileTransfer(fileUri, file)).start();
            }
        }
    }

    private void handleFileTransfer(Uri fileUri, File file) {
        try (InputStream fileInputStream = getContentResolver().openInputStream(fileUri);
             FileOutputStream fileOutputStream = new FileOutputStream(file)) {

            if (fileInputStream != null) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                    fileOutputStream.write(buffer, 0, bytesRead);
                }
                long fileSize = file.length();
                Log.d("OnlineChatActivity", "File size: " + fileSize + " bytes");
                //0，本人，ip对应人
                if ("client".equals(identity) && client != null) {
                    client.sendFile(file); // 发送文件
                    showToast("文件发送完成，大小: " + fileSize + " bytes");
                } else if ("service".equals(identity) && server != null) {
                    server.sendFile(file);
                    showToast("文件发送完成，大小: " + fileSize + " bytes");
                }
                fileRepository.insertFile(file.getName(), System.currentTimeMillis(), "0");
                list.add(new ChatInfo(file.getName(),2));
                updateUI();
            }
        } catch (IOException e) {
            Log.e("OnlineChatActivity", "处理文件时出错: " + e.getMessage());
            showToast("处理文件时出错");
        }
    }

    private void handleByIdentity() {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        if ("service".equals(identity)) {
            executor.execute(() -> {
                try {
                    server = new Server(PORT, this);
                    server.setListener(message -> {
                        runOnUiThread(() -> {
                            messageRepository.insertMessage(message, 1);
                            list.add(new ChatInfo(1, message));
                            updateUI();
                        });
                    }, fileName -> {
                        fileRepository.insertFile(fileName, System.currentTimeMillis(), serverAddress);
                        list.add(new ChatInfo(fileName,3));
                        updateUI();
                    });
                    server.start();
                } catch (IOException e) {
                    Log.e("OnlineChatActivity", "初始化服务器时出错: " + e.getMessage());
                    runOnUiThread(() -> {
//                        showToast("初始化服务器时出错");
                        finish();
                    });
                }
            });
        } else if ("client".equals(identity)) {
            client = new Client(this);
            executor.execute(() -> {
                client.start(serverAddress, PORT);
                while (client != null) {
                    try {
                        String message = client.getNextMessage();
                        if (message != null) {
                            runOnUiThread(() -> {
                                messageRepository.insertMessage(message, 1);
                                list.add(new ChatInfo(1, message));
                                updateUI();
                            });
                        }
                        FileRepository.FileRecord fileRecord = client.getNextFile();
                        if (fileRecord != null) {
                            fileRepository.insertFile(fileRecord.getFileName(), fileRecord.getTimestamp(), fileRecord.getSender());
                            list.add(new ChatInfo(fileRecord.getFileName(),3));
                            updateUI();
                        }
                    } catch (Exception e) {
                        Log.e("OnlineChatActivity", "客户端通信出错: " + e.getMessage());
                        runOnUiThread(() -> showToast("客户端通信出错"));
                        break;
                    }
                }
            });
        }
    }

    private void sendClientMessage(String message) {
        new Thread(() -> {
            try {
                client.sendMessage(message);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            runOnUiThread(() -> {
                list.add(new ChatInfo(0, message));
                updateUI();
            });
        }).start();
    }

    private void sendServerMessage(String message) {
        new Thread(() -> {
            server.sendMessage(message);
            runOnUiThread(() -> {
                list.add(new ChatInfo(0, message));
                updateUI();
            });
        }).start();
    }

    private void updateUI() {
        runOnUiThread(() -> adapter.update(list));
    }

    private void showToast(final String message) {
        runOnUiThread(() -> Toast.makeText(this, message, Toast.LENGTH_LONG).show());
    }

    @SuppressLint("Range")
    private String getFileName(Uri uri) {
        String fileName = null;
        if ("content".equals(uri.getScheme())) {
            try (Cursor cursor = getContentResolver().query(uri, null, null, null, null)) {
                if (cursor != null && cursor.moveToFirst()) {
                    fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                }
            }
        } else if ("file".equals(uri.getScheme())) {
            fileName = new File(uri.getPath()).getName();
        }
        return fileName;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        close();
    }
    private void close(){
        if (client != null) {
            client.close();
        }
        if (server != null) {
            server.stop(); // 确保服务器被正确停止
        }
    }
}
